#ifndef __MCS__LEXER__HPP
#define __MCS__LEXER__HPP

#include "ParserDefines.hpp"
#include "InputStream.hpp"

class CodeParser;

class Lexer : public Object
{
public:
	Lexer(InputStream * stream);
	~Lexer();

	int yylex();

	ObjectPtr value() const { return value_; }
	SourceLocation location() const { return location_; }
private:
	enum CodeBlockType
	{
		OutsideCodeBlock,
		InLineBlock,
		EndOfLineBlock,
		MultiLineBlock,
	};

	enum CommentType
	{
		OutsideComment,
		EndOfLineComment,
		MultiLineComment,
	};

	enum State
	{
		UnitializedText,
		Text,
		AtSign,
		Code,
		Comment,
		MaybeEndOfBlock,
		MaybeEndOfComment,
		EndOfFile,
	};

	InputStream * stream_;
	ObjectPtr value_;
	SourceLocation location_;
	State state_;
	CodeBlockType codeBlockType_;
	CommentType commentType_;
	bool hasCode_;
	bool semiconPending_;
	SourceLocation semicolonLocation_;
	ptr<CodeParser> codeParser_;
};

#endif //__MCS__LEXER__HPP